package robot

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
)

// 发送消息机器人【企业微信】
// 文档 https://work.weixin.qq.com/api/doc/90000/90136/91770

func NewWechatRobot(key string) *WechatRobot {
	return &WechatRobot{
		key: key,
	}
}

type WechatRobot struct {
	key string
}

func (robot *WechatRobot) SendMessage(msg interface{}) error {
	body := bytes.NewBuffer(nil)
	err := json.NewEncoder(body).Encode(msg)
	if err != nil {
		return fmt.Errorf("msg json failed, msg: %v, err: %v", msg, err.Error())
	}

	value := url.Values{}
	value.Set("key", robot.key)
	request, err := http.NewRequest(http.MethodPost, "https://qyapi.weixin.qq.com/cgi-bin/webhook/send", body)
	if err != nil {
		return fmt.Errorf("error request: %v", err.Error())
	}
	request.URL.RawQuery = value.Encode()
	request.Header.Add("Content-Type", "application/json;charset=utf-8")
	res, err := (&http.Client{}).Do(request)
	if err != nil {
		return fmt.Errorf("send WeChat message failed, error: %v", err.Error())
	}
	defer func() { _ = res.Body.Close() }()
	result, err := io.ReadAll(res.Body)

	if res.StatusCode != 200 {
		return fmt.Errorf("send WeChat message failed, %s", httpError(request, res, result, "http code is not 200"))
	}
	if err != nil {
		return fmt.Errorf("send WeChat message failed, %s", httpError(request, res, result, err.Error()))
	}

	type response struct {
		ErrCode int `json:"errcode"`
	}
	var ret response

	if err := json.Unmarshal(result, &ret); err != nil {
		return fmt.Errorf("send WeChat message failed, %s", httpError(request, res, result, err.Error()))
	}

	if ret.ErrCode != 0 {
		return fmt.Errorf("send WeChat message failed, %s", httpError(request, res, result, "errcode is not 0"))
	}

	return nil
}

func (robot *WechatRobot) SendTextMessage(content string, atUserIds, atMobiles []string) error {
	msg := map[string]interface{}{
		"msgtype": "text",
		"text": map[string]interface{}{
			"content":               content,
			"mentioned_list":        atUserIds,
			"mentioned_mobile_list": atMobiles,
		},
	}

	return robot.SendMessage(msg)
}

func (robot *WechatRobot) SendMarkdownMessage(content string) error {
	msg := map[string]interface{}{
		"msgtype": "markdown",
		"markdown": map[string]string{
			"content": content,
		},
	}

	return robot.SendMessage(msg)
}

func (robot *WechatRobot) SendNewsMessage(title string, description string, url string, picUrl string) error {
	msg := map[string]interface{}{
		"msgtype": "news",
		"news": map[string]interface{}{
			"articles": map[string]string{
				"title":       title,
				"description": description,
				"url":         url,
				"picurl":      picUrl,
			},
		},
	}

	return robot.SendMessage(msg)
}
